/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package viev.model;

import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.parser.HtmlParseData;
import edu.uci.ics.crawler4j.url.WebURL;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 *
 * @author viev
 */
@ManagedBean
@SessionScoped
public class DBContext {

    private HibernateUtil helper;
    private Session session;

    public List<Category> getCategories() {
        session = helper.getSessionFactory().openSession();
        List<Category> categories = session.createCriteria(Category.class).list();
        return categories;
    }
    private List<Chanel> chanels = new ArrayList<Chanel>();

    public List<RSSLink> getRssLinks() {
        session = helper.getSessionFactory().openSession();
        List<RSSLink> links = session.createCriteria(RSSLink.class).add(Restrictions.eq("categoryId", categoryId)).list();
        chanels.clear();
        for (int i = 0; i < links.size(); i++) {
            RSSLink link = links.get(i);
            RSSFeedParser parser = new RSSFeedParser(link.getLink());
            chanels.add(parser.readFeed());
        }
        return links;
    }

    public List<RSSLink> getAllRssLinks() {
        session = helper.getSessionFactory().openSession();
        List<RSSLink> links = session.createCriteria(RSSLink.class).list();
        return links;
    }
    private int categoryId = 1;

    public String browse(int categoryId) {
        this.categoryId = categoryId;
        return "index?faces-redirect=true";
    }

    public String adminBrowse(int categoryId) {
        this.categoryId = categoryId;
        return "/Admin/index?faces-redirect=true";
    }
    private RSSLink selectedRSSLink;

    public RSSLink getSelectedRSSLink() {
        return selectedRSSLink;
    }
    private Category selectedCategory;

    public Category getSelectedCategory() {
        return selectedCategory;
    }

    public void setSelectedCategory(Category selectedCategory) {
        this.selectedCategory = selectedCategory;
    }

    public void setSelectedRSSLink(RSSLink selectedRSSLink) {
        this.selectedRSSLink = selectedRSSLink;
    }

    public String setAddNewRSSMode() {
        this.selectedRSSLink = new RSSLink();
        return "/Admin/RSS/add?faces-redirect=true";
    }

    public String setAddNewCategory() {
        this.selectedCategory = new Category();
        return "/Admin/Category/add?faces-redirect=true";
    }

    public String addRSSLink() {
        boolean returnVal = addRSSLink(selectedRSSLink);
        if (returnVal) {
            return "/Admin/index?faces-redirect=true";
        } else {
            return "/Admin/RSS/add?faces-redirect=true";
        }
    }

    public String addCategory() {
        boolean returnVal = addCategory(selectedCategory);
        if (returnVal) {
            return "/Admin/index?faces-redirect=true";
        } else {
            return "/Admin/Category/add?faces-redirect=true";
        }
    }

    private boolean addRSSLink(RSSLink link) {
        try {
            session = helper.getSessionFactory().openSession();
            session.beginTransaction();
            session.save(link);
            session.getTransaction().commit();
            session.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private boolean addCategory(Category category) {
        try {
            session = helper.getSessionFactory().openSession();
            session.beginTransaction();
            session.save(category);
            session.getTransaction().commit();
            session.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public String updateRSSLink() {
        boolean returnVal = updateRSSLink(selectedRSSLink);
        if (returnVal) {
            return "/Admin/index?faces-redirect=true";
        } else {
            return "/Admin/RSS/update?faces-redirect=true";
        }
    }

    public String updateCategory() {
        boolean returnVal = updateCategory(selectedCategory);
        if (returnVal) {
            return "/Admin/index?faces-redirect=true";
        } else {
            return "/Admin/Category/update?faces-redirect=true";
        }
    }

    private boolean updateRSSLink(RSSLink link) {
        try {
            session = helper.getSessionFactory().openSession();
            session.beginTransaction();
            session.update(link);
            session.getTransaction().commit();
            session.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private boolean updateCategory(Category category) {
        try {
            session = helper.getSessionFactory().openSession();
            session.beginTransaction();
            session.update(category);
            session.getTransaction().commit();
            session.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public String deleteRSSLink() {
        boolean returnVal = deleteRSSLink(selectedRSSLink);
        if (returnVal) {
            return "/Admin/index?faces-redirect=true";
        } else {
            return "/Admin/RSS/delete?faces-redirect=true";
        }
    }

    public String deleteCategory() {
        boolean returnVal = deleteCategory(selectedCategory);
        if (returnVal) {
            return "/Admin/index?faces-redirect=true";
        } else {
            return "/Admin/Category/delete?faces-redirect=true";
        }
    }

    private boolean deleteRSSLink(RSSLink link) {
        try {
            session = helper.getSessionFactory().openSession();
            session.beginTransaction();
            session.delete(link);
            session.getTransaction().commit();
            session.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private boolean deleteCategory(Category category) {
        try {
            session = helper.getSessionFactory().openSession();
            session.beginTransaction();
            session.delete(category);
            session.getTransaction().commit();
            session.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public String setRSSLinkToUpdate(RSSLink rssLink) {
        this.selectedRSSLink = rssLink;
        return "/Admin/RSS/update?faces-redirect=true";
    }

    public String setCategoryToUpdate(Category category) {
        this.selectedCategory = category;
        return "/Admin/Category/update?faces-redirect=true";
    }

    public String setRSSLinkToDelete(RSSLink rssLink) {
        this.selectedRSSLink = rssLink;
        return "/Admin/RSS/delete?faces-redirect=true";
    }

    public String setCategoryToDelete(Category category) {
        this.selectedCategory = category;
        return "/Admin/Category/delete?faces-redirect=true";
    }

    private boolean adminLogin(User login) {
        return false;
    }
    private User login;

    private boolean isLogin() {
        return login != null;
    }

    public String login() {
        adminLogin(login);
        return "/Admin/index?faces-redirect=true";
    }
    private Item selectedItem;

    public List<Item> getItems() {
        List<Item> lst = new ArrayList<Item>();
        for (Chanel chanel : chanels) {
            lst.addAll(chanel.getItems());
        }
        return lst;
    }

    public String setShowPage(Item selectedItem) {
        this.selectedItem = selectedItem;
        return "/Home/page?faces-redirect=true";
    }

    public String getTextContent() throws IOException {
        try {
            URL url = new URL(selectedItem.getLink());
            SocketAddress addr = new InetSocketAddress("proxy", 8080);
            Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
            BufferedReader dis = new BufferedReader(new InputStreamReader(url.openConnection(proxy).getInputStream(), "UTF-8"));
            final ArrayList<String> list = new ArrayList<String>();

            ParserDelegator parserDelegator = new ParserDelegator();
            HTMLEditorKit.ParserCallback parserCallback = new HTMLEditorKit.ParserCallback() {
                @Override
                public void handleText(final char[] data, final int pos) {
                    list.add(new String(data));
                }

                @Override
                public void handleStartTag(HTML.Tag tag, MutableAttributeSet attribute, int pos) {
                }

                @Override
                public void handleEndTag(HTML.Tag t, final int pos) {
                }

                @Override
                public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, final int pos) {
                }

                @Override
                public void handleComment(final char[] data, final int pos) {
                }

                @Override
                public void handleError(final java.lang.String errMsg, final int pos) {
                }
            };
            parserDelegator.parse(dis, parserCallback, true);
            StringBuilder builder = new StringBuilder();
            int max = 0;
            for (String line : list) {
                if (line.trim().length() > max) {
                    max = line.length();
                }
            }
            builder.append("<h3>").append(selectedItem.getTitle()).append("</h3>");
            builder.append("<span>").append(selectedItem.getPubDate()).append("</span>").append(" <a href=" + selectedItem.getLink() + ">source</a><br/>");
            for (String s : list) {
                if (s.trim().length() > 0.2 * max) {
                    builder.append(s).append("\n<br/>\n");
                }
            }
            return builder.toString();
        } catch (Exception e) {
            return "";
        }
    }

    public String getMainContent() {
        String error = "";
        try {   
            System.getProperties().put("http.proxyHost", "10.22.152.254");
            System.getProperties().put("http.proxyPort", "8080");

            Document doc = Jsoup.connect(selectedItem.getLink()).get();

            Elements elements = doc.select("p, span, h1, h2, h3, h4");
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < elements.size(); i++) {
                result.append(elements.get(i).toString());
            }
            return result.toString().replaceAll("href=\".*?\"", "");
        } catch (Exception e) {
            error += e.getMessage();
        }
        return "Sory, cannot get content! Error: " + error;
    }
}
